package com.lclz.util;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.codehaus.jackson.jaxrs.JsonMappingExceptionMapper;
import org.codehaus.jackson.jaxrs.JsonParseExceptionMapper;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.client.urlconnection.HTTPSProperties;

public class JerseyClientLazyLoadedSingleton {

	private final static boolean skipHttpsCheck = false;
	private Client jerseyClient = null;

	public static Client getInstance() {
		return LazyHolder.singletonInstatnce.jerseyClient;
	}

	private static class LazyHolder { // holds the singleton class
		private static final JerseyClientLazyLoadedSingleton singletonInstatnce = new JerseyClientLazyLoadedSingleton();
	}

	private JerseyClientLazyLoadedSingleton() {
		ClientConfig config = new DefaultClientConfig();
		config.getProperties().put(ClientConfig.PROPERTY_THREADPOOL_SIZE, 10);
		config.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT,
				30 * 1000);
		config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING,
				Boolean.TRUE);
		config.getClasses().add(JacksonJaxbJsonProvider.class);
		config.getClasses().add(JacksonJsonProvider.class);
		config.getClasses().add(JsonParseExceptionMapper.class);
		config.getClasses().add(JsonMappingExceptionMapper.class);
		if (!skipHttpsCheck) {
			try {
				SSLContext sslContext = SSLContext.getInstance("TLS");
				TrustManager xtm = new X509TrustManager() {
					@Override
					public void checkClientTrusted(
							java.security.cert.X509Certificate[] chain,
							String authType)
							throws java.security.cert.CertificateException {
					}

					@Override
					public void checkServerTrusted(
							java.security.cert.X509Certificate[] chain,
							String authType)
							throws java.security.cert.CertificateException {
					}

					@Override
					public java.security.cert.X509Certificate[] getAcceptedIssuers() {
						return null;
					}
				};
				TrustManager[] xtmArray = new TrustManager[] { xtm };
				sslContext.init(null, xtmArray, null);
				HostnameVerifier hnv = new HostnameVerifier() {
					public boolean verify(String hostname, SSLSession session) {
						return true;
					}
				};
				config.getProperties().put(
						HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
						new HTTPSProperties(hnv, sslContext));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		jerseyClient = Client.create(config);
	}

}
